#Requires -Version 3.0
Set-StrictMode -Version 2
$script:clusterPath = Resolve-Path "$PSScriptRoot/../conf/clusters"
$script:isWindows = $env:OS -eq 'Windows_NT'
$script:defaultCluster = $env:HBASE_CLUSTER

function Set-HBaseCluster
{
    Param
    (
        # The HBase cluster name
        [Parameter(Mandatory=$true,
                   Position=0)]
        [string]
        $Cluster
    )

    if($Cluster) {
        $configurationPath = Join-Path $script:clusterPath $Cluster
        if (-not (Test-Path $configurationPath)) {
            throw "Configurations of cluster $Cluster not exists, please check files under $script:clusterPath"
        }
        $env:HBASE_CLUSTER = $configurationPath
    }
}

function Reset-HBaseCluster
{
    $env:HBASE_CLUSTER = $script:defaultCluster
}

function Start-HBaseViewer
{
<#
.SYNOPSIS
    Starts HBase Viewer.
.DESCRIPTION
    Starts the HViewer.
.EXAMPLE
    Start-HBaseViewer.ps1
.NOTES
#>
    Write-Verbose "Running '$PSScriptRoot/hbase viewer'..."
    if($script:isWindows) {
        & CMD /c $PSScriptRoot/hbase.bat viewer
    } else {
        & sh $PSScriptRoot/hbase viewer
    }
}

function Dump-HBaseTable
{
<#
.SYNOPSIS
    Dump specified HBase table rows.
.DESCRIPTION
    Dump specified HBase table rows to csv file.
.EXAMPLE
    Dump-HBaseTable -TableName dscat:_asrbal_global_0.0.1 -OutFile D:\hbase.csv -Query @{FundamentalSeriesId='48433149979'} -Cluster Mimas
    or
    Dump-HBaseTable -TableName dscat:_asrbal_global_0.0.1 -OutFile D:\hbase.csv -QueryString 'FundamentalSeriesId=48433149979' -Cluster Mimas

    Those commands dump the data which FundamentalSeriesId equals '48433149979' in the dscat:_asrbal_global_0.0.1 table and save to file D:\hbase.csv.
.EXAMPLE
    Dump-HBaseTable -TableName dscat:_asrbal_global_0.0.1 -OutFile D:\hbase.csv -Query @{FundamentalSeriesId='48433149979';CumulativeType='N'} -Cluster Mimas
    or
    Dump-HBaseTable -TableName dscat:_asrbal_global_0.0.1 -OutFile D:\hbase.csv -QueryString 'FundamentalSeriesId=48433149979&CumulativeType=N' -Cluster Mimas

    Those commands dump the data which FundamentalSeriesId equals '48433149979' and CumulativeType equals 'N' in the dscat:_asrbal_global_0.0.1 table and save to file D:\hbase.csv.
.EXAMPLE
    Import-Csv D:\Query.csv | Dump-HBaseTable.ps1 -Cluster Mimas

    This command performs a bulk dump defined in the D:\Query.csv with below content:

    TableName,OutFile,QueryString
    dscat:_asrbal_global_0.0.1,D:\asrbal_global.csv,FundamentalSeriesId=48433149979
    dscat:_proformareason_0.0.1,D:\\proformareason.csv,FundamentalSeriesId=48433340183&CumulativeType=N
.NOTES
#>
    [CmdletBinding(DefaultParameterSetName='HASH')]
    Param
    (
        # HBase table name
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [ValidateNotNullOrEmpty()]
        [string]
        $TableName,

        # Output file path
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=1)]
        [ValidateNotNullOrEmpty()]
        [Alias("PSPath")]
        [string]
        $OutFile,

        # Row key component query hash maps
        [Parameter(Mandatory=$true,
                   ParameterSetName='HASH',
                   Position=2)]
        [ValidateNotNullOrEmpty()]
        [Hashtable]
        $Query,

        # Row key component query string with '&' as delimiter
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='STRING',
                   Position=2)]
        [ValidateNotNullOrEmpty()]
        [String]
        $QueryString,

        # The HBase cluster name
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$false,
                   Position=3)]
        [string]
        $Cluster
    )

    Process {
        Set-HBaseCluster -Cluster $Cluster

        switch ($PSCmdlet.ParameterSetName)
        {
            'HASH' {
                $queryItems = @()
                foreach($item in $Query.Keys) {
                    $queryItems += "$item=$($Query[$item])"
                }
                $QueryString = $queryItems -join '&'
            }
        }
        $escapedQueryString = $queryString -replace '&', '"&"'

        $uri = "hbase://.env/default/$TableName/cf?$escapedQueryString"

        Write-Verbose "Running $PSScriptRoot/hbase dump $uri --out-file=`"$OutFile`""

        if($script:isWindows) {
            & $PSScriptRoot/hbase.bat dump "$uri" "--out-file=`"$OutFile`""
            $exitCode = $LASTEXITCODE
        } else {
            $process = Start-Process $PSScriptRoot/hbase -ArgumentList dump,$uri,"--out-file=`"$OutFile`"" -NoNewWindow -Wait -PassThru
            $exitCode = $process.ExitCode
        }
        if($exitCode) {
            throw "Failed to dump table $TableName with error $exitCode)"
        }
    }

    End {
        Reset-HBaseCluster
    }
}

Set-Alias hdumper Dump-HBaseTable
Set-Alias hviewer Start-HBaseViewer

Export-ModuleMember -Alias * -Function @(
    "Dump-HBaseTable"
    "Start-HBaseViewer"
)
